<div class="tmd-doc">
<h1 class="tmd-header-1">
Syntax/Semantics Exceptions in Go
</h1>
<p></p>
<div class="tmd-usual">
This article will list all kinds of syntax/semantics exceptions in Go. Some of these exceptions are syntactic sugars to make programming convenient, some are caused built-in generic privileges, some exists for history reasons, and some exists for other reasons in logic.
</div>
<p></p>
<h3 id="nest-function-calls" class="tmd-header-3">
Nested function calls
</h3>
<p></p>
<div class="tmd-usual">
The basic rule:
</div>
<div class="tmd-callout alert alert-info">
<div class="tmd-callout-content">
<div class="tmd-usual">
If the number of the return results of a function call is not zero, and the return results can be used as the whole arguments of another function call, then the former function call can be nested in the latter function call, the former nested call can't mix up with other arguments of the latter nesting call.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Sugar:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
If a function call returns exactly one result, then the function call can be always be used as a single-value argument in other function calls, the single-result function call can mix up with other arguments of the nesting function calls.
</div>
</div>
</div>
<p></p>
<p></p>
<div class="tmd-usual">
Example:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import (
	"fmt"
)

func f0() float64 {return 1}
func f1() (float64, float64) {return 1, 2}
func f2(float64, float64) {}
func f3(float64, float64, float64) {}
func f4()(x, y []int) {return}
func f5()(x map[int]int, y int) {return}

type I interface {m()(float64, float64)}
type T struct{}
func (T) m()(float64, float64) {return 1, 2}

func main() {
	// These lines compile okay.
	f2(f0(), 123)
	f2(f1())
	fmt.Println(f1())
	_ = complex(f1())
	_ = complex(T{}.m())
	f2(I(T{}).m())

	// These lines don't compile.
	/*
	f3(123, f1())
	f3(f1(), 123)
	*/

	// This line compiles okay only since
	// Go Toolchain 1.15.
	println(f1())

	// The following 3 lines compile okay
	// only since Go Toolchain 1.13.
	copy(f4())
	delete(f5())
	_ = complex(I(T{}).m())
}
</code></pre>
<p></p>
<p></p>
<h3 class="tmd-header-3">
Select struct fields
</h3>
<p></p>
<div class="tmd-usual">
The basic rule:
</div>
<div class="tmd-callout alert alert-info">
<div class="tmd-callout-content">
<div class="tmd-usual">
Pointer values have no fields.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Sugar:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
We can select the fields of a struct value through pointers of the struct value.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Example:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

type T struct {
	x int
}

func main() {
	var t T
	var p = &amp;t

	p.x *= 2
	// The above line is a sugar of the following line.
	(*p).x *= 2
}
</code></pre>
<p></p>
<h3 class="tmd-header-3">
Receiver arguments of method calls
</h3>
<p></p>
<div class="tmd-usual">
The basic rule:
</div>
<div class="tmd-callout alert alert-info">
<div class="tmd-callout-content">
<div class="tmd-usual">
The methods explicitly declared for type <code class="tmd-code-span">*T</code> are not methods of type <code class="tmd-code-span">T</code> for sure.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Sugar:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
Although the methods explicitly declared for type <code class="tmd-code-span">*T</code> are not methods of type <code class="tmd-code-span">T</code>, addressable values of type <code class="tmd-code-span">T</code> can be used as the receiver arguments of calls to these methods.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Example:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

type T struct {
	x int
}

func (pt *T) Double() {
	pt.x *= 2
}

func main() {
	// T{3}.Double() // This line fails to compile.

	var t = T{3}

	t.Double() // t.x == 6 now
	// The above line is a sugar of the following line.
	(&amp;t).Double() // t.x == 12 now
}
</code></pre>
<p></p>
<h3 class="tmd-header-3">
Take addresses of composite literal values
</h3>
<p></p>
<div class="tmd-usual">
The basic rule:
</div>
<div class="tmd-callout alert alert-info">
<div class="tmd-callout-content">
<div class="tmd-usual">
Literal values are unaddressable and unaddressable values can't be taken addresses.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Sugar:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
Although composite literal values are not addressable, they can be taken addresses explicitly.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Please read <a href="struct.html#take-composite-literal-address">structs</a> and <a href="container.html#take-composite-literal-address">containers</a> for details.
</div>
<p></p>
<p></p>
<h3 class="tmd-header-3">
Selectors on named one-Level pointers
</h3>
<p></p>
<div class="tmd-usual">
The basic rule:
</div>
<div class="tmd-callout alert alert-info">
<div class="tmd-callout-content">
<div class="tmd-usual">
Generally, selectors can't be used on values of <a href="type-system-overview.html#underlying-type">named</a> pointer types.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Sugar:
</div>
<div class="tmd-callout alert alert-info">
<div class="tmd-callout-content">
<div class="tmd-usual">
If <code class="tmd-code-span">x</code> is a value of a named one-level pointer type, and selector <code class="tmd-code-span">(*x).f</code> is a legal selector, then the <code class="tmd-code-span">x.f</code> is also a legal selector, it can be viewed as a shorthand of <code class="tmd-code-span">(*x).f</code>.
</div>
</div>
</div>
<p></p>
<p></p>
<div class="tmd-usual">
Selectors can never be used on values of <span class="tmd-bold">multi-level</span> pointer types, no matter whether the multi-level pointer types are named or not.
</div>
<p></p>
<div class="tmd-usual">
Exception of the sugar:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
The sugar is only valid if <code class="tmd-code-span">f</code> denotes a struct field, it is not valid if <code class="tmd-code-span">f</code> denotes a method.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Example:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

type T struct {
	x int
}

func (T) y() {
}

type P *T
type PP **T // a multi-level pointer type

func main() {
	var t T
	var p P = &amp;t
	var pt = &amp;t   // type of pt is *T
	var ppt = &amp;pt // type of ppt is **T
	var pp PP = ppt
	_ = pp

	_ = (*p).x // legal
	_ = p.x    // also legal (for x is a field)

	_ = (*p).y // legal
	// _ = p.y // illegal (for y is a method)

	// Following ones are all illegal.
	/*
	_ = ppt.x
	_ = ppt.y
	_ = pp.x
	_ = pp.y
	*/
}
</code></pre>
<p></p>
<p></p>
<h3 class="tmd-header-3">
The addressability of a container and its elements
</h3>
<p></p>
<div class="tmd-usual">
The basic rule:
</div>
<div class="tmd-callout alert alert-info">
<div class="tmd-callout-content">
<div class="tmd-usual">
If a container is addressable, then its elements are also addressable.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Exception:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
Elements of a map are always unaddressable, even if the map itself is addressable.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Sugar:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
Elements of a slice are always addressable, even if the slice itself is not addressable.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Example:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

func main() {
	var m = map[string]int{"abc": 123}
	_ = &amp;m // okay

	// The exception:
	// p = &amp;m["abc"] // error: map elements are unaddressable

	// The sugar:
	f := func() []int { // return results are unaddressable
		return []int{0, 1, 2}
	}
	// _ = &amp;f() // error: f() is unaddressable
	_ = &amp;f()[2] // okay
}
</code></pre>
<p></p>
<h3 class="tmd-header-3">
Modify unaddressable values
</h3>
<p></p>
<div class="tmd-usual">
The basic rule:
</div>
<div class="tmd-callout alert alert-info">
<div class="tmd-callout-content">
<div class="tmd-usual">
Unaddressable values can't be modified. In other words, unaddressable values shouldn't appear in assignments as destination values.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Exception:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
Although map element values are unaddressable, they can be modified and appear in assignments as destination values. (But map elements can't be modified partially, they can only be overwritten wholly, a.k.a., replaced.)
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Example:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

func main() {
	type T struct {
		x int
	}

	var mt = map[string]T{"abc": {123}}
	// Map elements are unaddressable.
	// _ = &amp;mt["abc"] // error
	// Partial modification is not allowed.
	// mt["abc"].x = 456 // error
	// It is ok to replace a map element as a whole.
	mt["abc"] = T{x: 789}
}
</code></pre>
<p></p>
<h3 class="tmd-header-3">
Function Parameters
</h3>
<p></p>
<div class="tmd-usual">
The basic rule:
</div>
<div class="tmd-callout alert alert-info">
<div class="tmd-callout-content">
<div class="tmd-usual">
Each parameter is a value of some type.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Exception:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
The first parameters of the built-in <code class="tmd-code-span">make</code> and <code class="tmd-code-span">new</code> functions are types.
</div>
</div>
</div>
<p></p>
<h3 class="tmd-header-3">
Function names in one package
</h3>
<p></p>
<div class="tmd-usual">
The basic rule:
</div>
<div class="tmd-callout alert alert-info">
<div class="tmd-callout-content">
<div class="tmd-usual">
Names of declared functions can't be duplicated in one package.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Exception:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
There can be multiple functions declared with names as <code class="tmd-code-span">init</code> (and types as <code class="tmd-code-span">func()</code>).
</div>
</div>
</div>
<p></p>
<h3 class="tmd-header-3">
Function calls
</h3>
<p></p>
<div class="tmd-usual">
The basic rule:
</div>
<div class="tmd-callout alert alert-info">
<div class="tmd-callout-content">
<div class="tmd-usual">
Functions whose names are not the blank identifier can be called in user code.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Exception:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
<code class="tmd-code-span">init</code> functions can't be called in user code.
</div>
</div>
</div>
<p></p>
<h3 class="tmd-header-3">
Functions being used as values
</h3>
<p></p>
<div class="tmd-usual">
The basic rule:
</div>
<div class="tmd-callout alert alert-info">
<div class="tmd-callout-content">
<div class="tmd-usual">
Declared functions can be used as function values.
</div>
</div>
</div>
<p></p>
<p></p>
<div class="tmd-usual">
Exception:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
<code class="tmd-code-span">init</code> functions can not be used as function values.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Example:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import "fmt"
import "unsafe"

func init() {}

func main() {
	// These ones are okay.
	var _ = main
	var _ = fmt.Println

	// This one fails to compile.
	var _ = init
}
</code></pre>
<p></p>
<h3 id="generic-arguments-passing" class="tmd-header-3">
The manners of type argument passing
</h3>
<p></p>
<div class="tmd-usual">
The basic rule:
</div>
<div class="tmd-callout alert alert-info">
<div class="tmd-callout-content">
<div class="tmd-usual">
In a type argument list, all type arguments are enclosed in square brackets and they are separated by commas in the list.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Exception:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
The manners of type argument lists passed to built-in generic type instantiations vary in different forms. Each key type argument of instantiated map types is individually enclosed in square brackets. Other type arguments are not enclosed. The type argument of an instantiation of built-in <code class="tmd-code-span">new</code> generic function is enclosed in parentheses. The type argument of an instantiation of the built-in <code class="tmd-code-span">make</code> generic function is mixed with value arguments and these type and value arguments are enclosed in parentheses.
</div>
</div>
</div>
<p></p>
<h3 id="discard-return-results" class="tmd-header-3">
Discard return values of function calls
</h3>
<p></p>
<div class="tmd-usual">
The basic rule:
</div>
<div class="tmd-callout alert alert-info">
<div class="tmd-callout-content">
<div class="tmd-usual">
The return values of a function call can be discarded altogether.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Exception:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
The return values of calls to the built-in functions which are documented in the <code class="tmd-code-span">builtin</code> and <code class="tmd-code-span">unsafe</code> standard packages, can't be discarded, if the called function has return results.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Exception in exception:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
The return values of a call to the built-in <code class="tmd-code-span">copy</code> and <code class="tmd-code-span">recover</code> functions can be all discarded, even if the two functions have return results.
</div>
</div>
</div>
<p></p>
<h3 class="tmd-header-3">
Declared variables
</h3>
<p></p>
<div class="tmd-usual">
The basic rule:
</div>
<div class="tmd-callout alert alert-info">
<div class="tmd-callout-content">
<div class="tmd-usual">
Declared variables are always addressable.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Exception:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
The <a href="https://golang.org/pkg/builtin/#pkg-variables">predeclared <code class="tmd-code-span">nil</code></a> variable is not addressable.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
So, <code class="tmd-code-span">nil</code> is an immutable variable.
</div>
<p></p>
<p></p>
<h3 class="tmd-header-3">
Argument passing
</h3>
<p></p>
<div class="tmd-usual">
The basic rule:
</div>
<div class="tmd-callout alert alert-info">
<div class="tmd-callout-content">
<div class="tmd-usual">
An argument can be passed to the corresponding function parameter only if the argument is assignable to the corresponding function parameter type.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Sugar:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
If the first slice argument of a <code class="tmd-code-span">copy</code> and <code class="tmd-code-span">append</code> function call is a byte slice, then the second argument can be a string, whereas a string value is not assignable to the second parameter type (also a byte slice). (For an <code class="tmd-code-span">append</code> call, assume the second argument is passed with the form <code class="tmd-code-span">arg...</code>.)
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Example:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

func main() {
	var bs = []byte{1, 2, 3}
	var s = "xyz"

	copy(bs, s)
	// The above line is a sugar (and an optimization)
	// for the following line.
	copy(bs, []byte(s))

	bs = append(bs, s...)
	// The above line is a sugar (and an optimization)
	// for the following line.
	bs = append(bs, []byte(s)...)
}
</code></pre>
<p></p>
<h3 class="tmd-header-3">
Comparisons
</h3>
<p></p>
<div class="tmd-usual">
The basic rule:
</div>
<div class="tmd-callout alert alert-info">
<div class="tmd-callout-content">
<div class="tmd-usual">
Map, slice and function types don't support comparison.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Exception:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
Map, slice and function values can be compared to the predeclared untyped <code class="tmd-code-span">nil</code> identifier.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Example:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

func main() {
	var s1 = []int{1, 2, 3}
	var s2 = []int{7, 8, 9}
	//_ = s1 == s2 // error: slice values can't be compared
	_ = s1 == nil // ok
	_ = s2 == nil // ok

	var m1 = map[string]int{}
	var m2 = m1
	// _ = m1 == m2 // error: map values can't be compared
	_ = m1 == nil
	_ = m2 == nil

	var f1 = func(){}
	var f2 = f1
	// _ = f1 == f2 // error: functions can't be compared
	_ = f1 == nil
	_ = f2 == nil
}
</code></pre>
<p></p>
<h3 class="tmd-header-3">
Comparisons 2
</h3>
<p></p>
<div class="tmd-usual">
The basic rule:
</div>
<div class="tmd-callout alert alert-info">
<div class="tmd-callout-content">
<div class="tmd-usual">
If a value can be implicitly converted to a comparable type, then the value can be compared to the values of the comparable type.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Exception:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
The values of a non-interface incomparable type can't be compared to values of an interface type, even if the non-interface incomparable type implements the interface type (so values of the non-interface incomparable type can be implicitly converted to the interface type).
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Please read <a href="value-conversions-assignments-and-comparisons.html#comparison-rules">comparison rules</a> for examples.
</div>
<p></p>
<p></p>
<p></p>
<h3 class="tmd-header-3">
Blank composite literals
</h3>
<p></p>
<div class="tmd-usual">
The basic rule:
</div>
<div class="tmd-callout alert alert-info">
<div class="tmd-callout-content">
<div class="tmd-usual">
If the values of a type <code class="tmd-code-span">T</code> can be represented with composite literals, then <code class="tmd-code-span">T{}</code> is its zero value.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Exception:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
For a map or a slice type <code class="tmd-code-span">T</code>, <code class="tmd-code-span">T{}</code> isn't its zero value. Its zero value is represented with <code class="tmd-code-span">nil</code>.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Example:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import "fmt"

func main() {
	// new(T) returns the address of a zero value of type T.

	type T0 struct {
		x int
	}
	fmt.Println( T0{} == *new(T0) ) // true
	type T1 [5]int
	fmt.Println( T1{} == *new(T1) ) // true

	type T2 []int
	fmt.Println( T2{} == nil ) // false
	type T3 map[int]int
	fmt.Println( T3{} == nil ) // false
}
</code></pre>
<p></p>
<h3 class="tmd-header-3">
Container element iterations
</h3>
<p></p>
<div class="tmd-usual">
The basic rule:
</div>
<div class="tmd-callout alert alert-info">
<div class="tmd-callout-content">
<div class="tmd-usual">
Only container values can be ranged, the iterated values are container elements. The element key/index will also be returned alongside of each iterated element.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Exception 1:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
The iterated values are runes if the ranged containers are strings, instead of the byte elements of strings.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Exception 2:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
The element index (order) will not be returned alongside of each iterated element when iterating channels.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Sugar:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
Array pointers can also be ranged to iterate array elements, though pointers are not containers.
</div>
</div>
</div>
<p></p>
<h3 class="tmd-header-3">
Methods of built-in types
</h3>
<p></p>
<div class="tmd-usual">
The basic rule:
</div>
<div class="tmd-callout alert alert-info">
<div class="tmd-callout-content">
<div class="tmd-usual">
Generally, built-in types have no methods.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Exception:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
The built-in <code class="tmd-code-span">error</code> type has a <code class="tmd-code-span">Error() string</code> method.
</div>
</div>
</div>
<p></p>
<p></p>
<h3 class="tmd-header-3">
Types of values
</h3>
<p></p>
<div class="tmd-usual">
The basic rule:
</div>
<div class="tmd-callout alert alert-info">
<div class="tmd-callout-content">
<div class="tmd-usual">
Each value has either a type or a default type.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Exception:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
Untyped <code class="tmd-code-span">nil</code> has neither a type nor a default type.
</div>
</div>
</div>
<p></p>
<h3 class="tmd-header-3">
Constant values
</h3>
<p></p>
<div class="tmd-usual">
The basic rule:
</div>
<div class="tmd-callout alert alert-info">
<div class="tmd-callout-content">
<div class="tmd-usual">
Constant values never change. Constants can be assigned to variables.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Exception:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
Predeclared <code class="tmd-code-span">iota</code> is a built-in constant which is bound with <code class="tmd-code-span">0</code>, but its value is not constant. Its value will start from <code class="tmd-code-span">0</code> and increase one constant specification by constant specification in a constant declaration, though the increments happen at compile time.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Exception 2:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
<code class="tmd-code-span">iota</code> can only be used within constant declarations. It can't be assigned to variables in variable declarations.
</div>
</div>
</div>
<p></p>
<h3 id="behaviors-on-missing-optional-result" class="tmd-header-3">
Behavior change caused by discarding the optional evaluation results of expressions
</h3>
<p></p>
<div class="tmd-usual">
The basic rule:
</div>
<div class="tmd-callout alert alert-info">
<div class="tmd-callout-content">
<div class="tmd-usual">
Whether or not the optional evaluation result of an expression presents will not affect program behavior.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Exception:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
Missing the optional result value in a type assertion will make current goroutine panic if the type assertion fails.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Example:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

func main() {
	var ok bool

	var m = map[int]int{}
	_, ok = m[123] // will not panic
	_ = m[123]     // will not panic

	var c = make(chan int, 2)
	c &lt;- 123
	close(c)
	_, ok = &lt;-c // will not panic
	_ = &lt;-c     // will not panic

	var v interface{} = "abc"
	_, ok = v.(int) // will not panic
	_ = v.(int)     // will panic!
}
</code></pre>
<p></p>
<h3 id="code-block-following-else" class="tmd-header-3">
<code class="tmd-code-span">else</code> keyword followed by a code block
</h3>
<p></p>
<div class="tmd-usual">
The basic rule:
</div>
<div class="tmd-callout alert alert-info">
<div class="tmd-callout-content">
<div class="tmd-usual">
The <code class="tmd-code-span">else</code> keyword must be followed by an explicit code block <code class="tmd-code-span">{...}</code>.
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
Sugar:
</div>
<div class="tmd-callout alert alert-success">
<div class="tmd-callout-content">
<div class="tmd-usual">
The <code class="tmd-code-span">else</code> keyword may be followed by a <code class="tmd-code-span">if</code> code block (which is implicit).
</div>
</div>
</div>
<p></p>
<div class="tmd-usual">
For example, in the following code, function <code class="tmd-code-span">foo</code> compiles okay, but function <code class="tmd-code-span">bar</code> doesn't.
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">func f() []int {
	return nil
}

func foo() {
	if vs := f(); len(vs) == 0 {
	} else if len(vs) == 1 {
	}

	if vs := f(); len(vs) == 0 {
	} else {
		switch {
		case len(vs) == 1:
		default:
		}
	}
	
	if vs := f(); len(vs) == 0 {
	} else {
		for _, _ = range vs {
		}
	}
}

func bar() {
	if vs := f(); len(vs) == 0 {
	} else switch { // error
	case len(vs) == 1:
	default:
	}
	
	if vs := f(); len(vs) == 0 {
	} else for _, _ = range vs { // error
	}
}
</code></pre>
<p></p>
</div>
